package com.foreveross.util;

import java.io.InputStream;
import java.io.StringReader;
import java.io.Writer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.xml.sax.InputSource;

import com.foreveross.weixin.vo.pay.PayUnifiedOrder;
import com.google.gson.Gson;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer;
import com.thoughtworks.xstream.io.xml.XppDriver;

public class XmlUtil{
	
	private static XStream xstream = new XStream(new XppDriver(new XmlFriendlyReplacer("_-", "_")));
	
	/** 
	 * 扩展xstream，使其支持CDATA块 
	 *  
	 * @date 2014-03-19 
	 */  
	private static XStream xstreamWithCDATA = new XStream(new XppDriver() {  
	    public HierarchicalStreamWriter createWriter(Writer out) {  
	        return new PrettyPrintWriter(out) {  
	            // 对所有xml节点的转换都增加CDATA标记  
	            boolean cdata = true;  
	  
	            public void startNode(String name, Class clazz) {  
	                super.startNode(name, clazz);  
	            }  
	  
	            protected void writeText(QuickWriter writer, String text) {  
	                if (cdata) {  
	                    writer.write("<![CDATA[");  
	                    writer.write(text);  
	                    writer.write("]]>");  
	                } else {  
	                    writer.write(text);  
	                }  
	            }  
	        };  
	    }  
	});
	
	
	/** 
	 * 解析XML 
	 *  
	 * @param request 
	 * @return 
	 * @throws Exception 
	 */  
	@SuppressWarnings("unchecked")  
	public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
	    // 将解析结果存储在HashMap中  
	    Map<String, String> map = new HashMap<String, String>();  
	  
	    // 从request中取得输入流  
	    InputStream inputStream = request.getInputStream();  
	    // 读取输入流  
	    SAXReader reader = new SAXReader();  
	    Document document = (Document) reader.read(inputStream);  
	    // 得到xml根元素  
	    Element root = document.getRootElement();  
	    // 得到根元素的所有子节点  
	    List<Element> elementList = root.elements();  
	  
	    // 遍历所有子节点  
	    for (Element e : elementList)  {
	    	String key = e.getName();
	    	String value = "".equals(e.getText()) ?null:
	    		e.getText().indexOf("/") != -1 ? e.getText().replace("/", "\\/") : e.getText();
	    	
	    	map.put(key, value);  
	    }
	       
	  
	    // 释放资源  
	    inputStream.close();  
	    inputStream = null;  
	  
	    return map;  
	} 
	
	@SuppressWarnings("unchecked")  
	public static String parseXmlByStr(String xmlStr) throws Exception {
		  // 将解析结果存储在HashMap中  
	    String str = null;
	    StringReader stringReader = null;
	    try{
	    	// 读取数据
	    	SAXReader reader = new SAXReader();
		    stringReader = new StringReader(xmlStr);
		    
			Document document = (Document) reader.read(new InputSource(
					stringReader));
		    // 得到xml根元素  
			Element root = document.getRootElement();
			str = (String)root.getData();
	    }catch(Exception e){
	    	e.printStackTrace();
	    }

	    return str;  
	}
	
	@SuppressWarnings("unchecked")  
	public static String parseXmlBySoap(String xmlStr) throws Exception {
	    // 将解析结果存储在HashMap中  
	    String str = null;
	    StringReader stringReader = null;
	    try{
	    	// 读取数据
	    	SAXReader reader = new SAXReader();
		    stringReader = new StringReader(xmlStr);
		    
			Document document = (Document) reader.read(new InputSource(
					stringReader));
		    // 得到xml根元素  
			Element root = document.getRootElement();
			//root.getData();
			Element sequenceEle = root.element("Body").element("GetSYS86ServiceResponse")
										.element("GetSYS86ServiceResult");
			str = (String)sequenceEle.getData();

	    }catch(Exception e){
	    	e.printStackTrace();
	    }

	  
	    return str;  
	} 
	
	/**
	 * 单个对象转换成XML
	 * @param obj 单个被转换的对象
	 * @return String
	 */
	public static String ClazzToXmlWithCDATA(Object obj) {  
		xstreamWithCDATA.alias("xml", obj.getClass());  
	    return xstreamWithCDATA.toXML(obj);  
	}  
	
	/**
	 * 单个对象转换成XML
	 * @param obj 单个被转换的对象
	 * @return String
	 */
	public static String ClazzToXml(Object obj) {  
		xstream.alias("xml", obj.getClass());  
	    return xstream.toXML(obj);  
	}  
	
	/**
	 * 单个对象转换成XML
	 * @param obj 单个被转换的对象
	 * @param subObj 被转换的对象里面的子集合对象
	 * @return String
	 */
	public static String ClazzToXmlWithCDATA(Object obj,Object subObj) {  
		xstreamWithCDATA.alias("xml", obj.getClass());  
		xstreamWithCDATA.alias("item", subObj.getClass()); 
	    return xstreamWithCDATA.toXML(obj);  
	} 
	
	/**
	 * 单个对象转换成XML
	 * @param obj 单个被转换的对象
	 * @param subObj 被转换的对象里面的子集合对象
	 * @return String
	 */
	public static String ClazzToXml(Object obj,Object subObj) {  
		xstream.alias("xml", obj.getClass());  
		xstream.alias("item", subObj.getClass()); 
	    return xstream.toXML(obj);  
	} 
	
	
	public static Object xmlToObject(String xml){
		return xstream.fromXML(xml);
	}
	
	public static Object xmlToObjectWithCDATA(String xml){
		return xstreamWithCDATA.fromXML(xml);
	}
 
}